package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zimi.mapper.*;
import com.zimi.model.*;
import com.zimi.util.CommonUtil;
import com.zimi.util.UserUtil;
import io.swagger.models.auth.In;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.commons.collections.list.SynchronizedList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 岗位功能授权表 Service
 *
 * @author lnintr
 * @since 2019-05-22
 */
@Service
public class SysPostSuperiorsService {

    @Autowired
    private SysPostSuperiorsExtendMapper extendMapper;
    @Autowired
    private CommonUtil commonUtil;
    @Autowired
    private SysPostSuperiorsMapper superiorsMapper;

    /**
     * @param orgId
     * @param postId
     * @return
     * @author wh
     * @desc 根据PostId 获取选中的id
     */
    public Map getSupPostChecked(int orgId, int postId,int limit, int page) {
        Map supMap = new HashMap();

        PageHelper.startPage(page, limit);
        List<SysPostSuperiorsExtend> result = new ArrayList<>();
        SysPostSuperiorsExtend superiorsExtend = (SysPostSuperiorsExtend) new SysPostSuperiorsExtend().setOriginOrgId(orgId).setPostId(postId).setState(1);

        List<SysPostSuperiorsExtend> list = extendMapper.getSupPostIsCheckList(superiorsExtend);
        PageInfo<SysPostSuperiorsExtend> pageInfo = new PageInfo<>(list);

        if (list != null && list.size() > 0) {
            for (SysPostSuperiorsExtend spse : list) {
                if (spse.getSuperiorsId() == 0) { //对默认岗位的名称要去机构表里面取根机构的岗位名
                    SysOrg tmpOrg = new SysOrg().selectById(spse.getOrgId());
                    SysOrg tmpOgn = new SysOrg().selectById(tmpOrg.getOgnId());

                    spse.setSuperiorsName(tmpOgn.getPostName());
                }

                result.add(spse);
            }
        }

        supMap.put("data",result);
        supMap.put("total",pageInfo.getTotal());
        return supMap;
    }

    public List<SysPostSuperiorsExtend> getSupPostunChecked(int orgId, int postId) {
        SysPostSuperiorsExtend superiorsExtend = (SysPostSuperiorsExtend) new SysPostSuperiorsExtend().setOriginOrgId(orgId).setPostId(postId).setState(2);
        List<SysPostSuperiorsExtend> list = extendMapper.getSupPostIsCheckList(superiorsExtend);

        return list;
    }

    /**
     * @author wh
     * @desc 获取本岗位所在的机构树
     */

    public List<SysOrgExtend> getCurOrgPost(SysOrgExtend orgExtend) {
        List<SysOrgExtend> result = new ArrayList<>();
        List<SysOrgExtend> list = commonUtil.getMineOrgPost(orgExtend);

        //取出所在岗位的ognId
        SysOrg tmpOrg = new SysOrg().selectById(orgExtend.getOrgId());

        if (list != null && list.size() > 0) {
            for (SysOrgExtend soe : list) {
                if (soe.getOgnId() == tmpOrg.getOgnId()) {
                    result.add(soe);
                }
                if (soe.getId() == null && soe.getOrgId() == tmpOrg.getOrgCate()) {
                    result.add(soe);
                }
            }
        }

        return result;
    }

    /**
     * @author wh
     * @desc 保存上级岗位
     */
    @Transactional
    public void save(SysPostSuperiors superiors) {
        Date dateTime = new Date();
        SysUser sysUser = UserUtil.getUser();

        int sort = 0;
        if (superiors.getId() == null) {
            List<SysPostSuperiors> list = new SysPostSuperiors().selectList(new LambdaQueryWrapper<SysPostSuperiors>().eq(SysPostSuperiors::getOriginOrgId, superiors.getOriginOrgId()).eq(SysPostSuperiors::getPostId, superiors.getPostId()).orderByDesc(SysPostSuperiors::getSort));

            //根据不同的originOrgId和postId 来处理sort
            if (list != null && list.size() > 0) {
                //获取同originOrgId和postId最大的sort
                sort = list.get(0).getSort();
                superiors.setSort(sort + 1);
            } else {
                superiors.setSort(sort + 1);
            }
            superiors.setCreateTime(dateTime);
            superiors.setCreateUser(sysUser.getId());

            superiors.insert();
        } else { //更新或删除
            // 1) 对修改对象进行行加锁
            SysPostSuperiors rowData = new SysPostSuperiors().selectOne(new LambdaQueryWrapper<SysPostSuperiors>().eq(SysPostSuperiors::getId, superiors.getId()).last("for update"));
            // 2)如果传过来的时间与行锁时间不同则抛出异常
            if (rowData.getUpdateTime() != null) { //确保是第二次修改才进入
                if (superiors.getUpdateTime().getTime() != rowData.getUpdateTime().getTime()) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                }
            }

            // 3) 修改数据
            superiors.setUpdateTime(dateTime);
            superiors.setUpdateUser(sysUser.getId());

            superiors.updateById();
        }
    }

    /**
     * @author wh
     * @desc 上移
     */
    @Transactional
    public void moveUp(SysPostSuperiors superiors) {
        List<SysPostSuperiors> list = new SysPostSuperiors().selectList(new LambdaQueryWrapper<SysPostSuperiors>().eq(SysPostSuperiors::getOriginOrgId, superiors.getOriginOrgId()).eq(SysPostSuperiors::getPostId, superiors.getPostId()).eq(SysPostSuperiors::getState, 1).orderByAsc(SysPostSuperiors::getSort));

        if (list != null && list.size() > 0) {
            List<SysPostSuperiors> tmpList = new ArrayList<>();

            for (SysPostSuperiors sps : list) {
                if (sps.getSort() < superiors.getSort()) {
                    tmpList.add(sps);
                }
            }

            if (tmpList.size() == 0) {
                throw new RuntimeException("已经到达顶部!");
            } else {
                //1. 取出上一行
                SysPostSuperiors UpSuperiors = tmpList.get(tmpList.size() - 1);

                //2 取出上一行的sort和id
                int upSort = UpSuperiors.getSort();
                int sort = superiors.getSort();
                int upId = UpSuperiors.getId();
                int id = superiors.getId();

                //3 交换sort
                UpSuperiors.setSort(sort);
                superiors.setSort(upSort);

                Map spsMap = new HashMap();
                spsMap.put(upId, UpSuperiors);
                spsMap.put(id, superiors);

                List<Integer> ids = new ArrayList<>();
                ids.add(upId);
                ids.add(id);

                //3 对要操作的两行添加行锁
                List<SysPostSuperiors> rowData = superiorsMapper.selectList(new QueryWrapper<SysPostSuperiors>().lambda().in(SysPostSuperiors::getId, ids).last("for update"));

                if (rowData == null || rowData.size() != 2) {
                    throw new RuntimeException("服务器关于交换顺序的数据异常。");
                }

                SysUser user = UserUtil.getUser();
                Date updateTime = new Date();

                for (SysPostSuperiors sps : rowData) {

                    SysPostSuperiors tmpSPS = (SysPostSuperiors) spsMap.get(sps.getId());
                    // 3）判断该数据已经被改过没有
                    if (sps.getUpdateTime() != null) {
                        if (tmpSPS.getUpdateTime() == null) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        } else {
                            if (sps.getUpdateTime().getTime() != tmpSPS.getUpdateTime().getTime()) {
                                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                            }
                        }
                    }

                    // 4)变更数据

                    tmpSPS.setUpdateUser(user.getId());
                    tmpSPS.setUpdateTime(updateTime);
                    tmpSPS.updateById();
                }
            }
        }
    }

    /**
     * @author wh
     * @desc 下移
     */
    @Transactional
    public void moveDown(SysPostSuperiors superiors) {

        List<SysPostSuperiors> list = new SysPostSuperiors().selectList(new LambdaQueryWrapper<SysPostSuperiors>().eq(SysPostSuperiors::getOriginOrgId, superiors.getOriginOrgId()).eq(SysPostSuperiors::getPostId, superiors.getPostId()).eq(SysPostSuperiors::getState, 1).orderByAsc(SysPostSuperiors::getSort));

        if (list != null && list.size() > 0) {
            List<SysPostSuperiors> tmpList = new ArrayList<>();

            for (SysPostSuperiors sps : list) {
                if (sps.getSort() > superiors.getSort()) {
                    tmpList.add(sps);
                }
            }

            if (tmpList.size() == 0) {
                throw new RuntimeException("已经到达底部!");
            } else {
                //1. 取出下一行
                SysPostSuperiors downSuperiors = tmpList.get(0);

                if (downSuperiors != null) {
                    //2 取出下一行的sort和id
                    int upSort = downSuperiors.getSort();
                    int sort = superiors.getSort();
                    int downId = downSuperiors.getId();
                    int id = superiors.getId();

                    //3 交换sort
                    downSuperiors.setSort(sort);
                    superiors.setSort(upSort);

                    Map spsMap = new HashMap();
                    spsMap.put(downId, downSuperiors);
                    spsMap.put(id, superiors);

                    List<Integer> ids = new ArrayList<>();
                    ids.add(downId);
                    ids.add(id);

                    //3 对要操作的两行添加行锁
                    List<SysPostSuperiors> rowData = superiorsMapper.selectList(new QueryWrapper<SysPostSuperiors>().lambda().in(SysPostSuperiors::getId, ids).last("for update"));

                    if (rowData == null || rowData.size() != 2) {
                        throw new RuntimeException("服务器关于交换顺序的数据异常。");
                    }

                    SysUser user = UserUtil.getUser();
                    Date updateTime = new Date();

                    for (SysPostSuperiors sps : rowData) {

                        SysPostSuperiors tmpSPS = (SysPostSuperiors) spsMap.get(sps.getId());
                        // 3）判断该数据已经被改过没有
                        if (sps.getUpdateTime() != null) {
                            if (tmpSPS.getUpdateTime() == null) {
                                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                            } else {
                                if (sps.getUpdateTime().getTime() != tmpSPS.getUpdateTime().getTime()) {
                                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                                }
                            }
                        }

                        // 4)变更数据

                        tmpSPS.setUpdateUser(user.getId());
                        tmpSPS.setUpdateTime(updateTime);
                        tmpSPS.updateById();
                    }
                }
            }
        }
    }
}



